package com.rwind.dynamic.service;

import com.rwind.dynamic.controller.MyController;
import com.rwind.dynamic.controller.QueryController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;


@Service
public class EndpointService {

    @Autowired
    private QueryController queryController;

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @PostConstruct
    public void init() {
        try {
            addMapping("/test4");
        } catch (NoSuchMethodException e) {

        }
        try {
            register(new MyController());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 接收请求参数格式： application/x-www-form-urlencoded
     * 应答格式: application/json ,关键是应答方法需要@ResponseBody注解
     * @param myController
     * @throws Exception
     */
    public void register(MyController myController) throws Exception {
        RequestMappingInfo mappingInfo = RequestMappingInfo.paths("/common").methods(RequestMethod.POST)
                .produces(MediaType.APPLICATION_JSON_VALUE)
                .consumes(MediaType.APPLICATION_FORM_URLENCODED_VALUE).build();
        Method method = myController.getClass().getMethod("commonRequest",HttpServletRequest.class, HttpServletResponse.class);
        requestMappingHandlerMapping.registerMapping(mappingInfo, myController, method);
    }

    /**
     * requestmappinginfo mappinginfo = requestmappinginfo
     *             .paths("/the/url")
     *             .methods(requestmethod.post)
     *             .consumes(mediatype.application_json_value)
     *             .produces(mediatype.application_json_value)
     *             .build();
     *
     * method meth = controllerclass.class.getmethod("controllermethod", requesttype.class));
     * mappinghandler.registermapping(mappinginfo, controller, meth);
     *
     *  public class controllerclass {
     *     public responseentity<responsetype> controllermethod (@requestbody requesttype request) {
     *         // service request
     *         return new responsetype();
     *     }
     * }
     */

    public void addMapping(String urlPath) throws NoSuchMethodException {

        /**
         * / 带一参数的get方法
         *         RequestMappingInfo requestMappingInfo1 = RequestMappingInfo.paths("/lmcTest2").params(new String[]{"fileName"}).methods(RequestMethod.GET).build();
         *         bean.registerMapping(requestMappingInfo1, "adapterController", AdapterController.class.getDeclaredMethod("myTest2", String.class));
         *         handler
         *         public Object myTest2(@RequestParam("fileName") String value) {
         *         return "this is my param : " + value;
         *     }
         */

        /**
         // 带多个参数的get方法
         RequestMappingInfo requestMappingInfo2 = RequestMappingInfo.paths("/lmcTest3")
         .params(new String[]{"fileName", "type", "isSort"})
         .methods(RequestMethod.GET).build();
         bean.registerMapping(requestMappingInfo2, "adapterController", AdapterController.class.getDeclaredMethod("myTest3", String.class, String.class, Boolean.class));

         Object myTest3(String fileName, String type, Boolean isSort) {
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("fileName", fileName);
         jsonObject.put("type", type);
         jsonObject.put("isSort", isSort);
         return "values : " + jsonObject.toJSONString();
         }

         */
        /*RequestMappingInfo requestMappingInfo = RequestMappingInfo
                .paths(urlPath)
                .methods(RequestMethod.GET)
                .produces(MediaType.APPLICATION_JSON_VALUE)
                .build();
        */

        /*requestMappingHandlerMapping.
                registerMapping(requestMappingInfo, queryController,
                        QueryController.class.getDeclaredMethod("handleRequests")
                );*/

        // body带参的post方法
        RequestMappingInfo requestMappingInfo5 = RequestMappingInfo.paths("/test4")
                //.produces("text/plain;charset=UTF-8")
                .produces(MediaType.APPLICATION_JSON_VALUE)
                .consumes(MediaType.APPLICATION_JSON_VALUE)
                .methods(RequestMethod.POST).build();
        requestMappingHandlerMapping.registerMapping(requestMappingInfo5, queryController,
                QueryController.class.getDeclaredMethod("myTest4", HttpServletRequest.class));


        // 注销接口
        //requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);


        /**
         *  // body带参的post方法
         *         RequestMappingInfo requestMappingInfo5 = RequestMappingInfo.paths("/lmcTest6")
         *                 .produces(new String[]{"text/plain;charset=UTF-8"})
         *                 .methods(RequestMethod.POST).build();
         *         bean.registerMapping(requestMappingInfo5, "adapterController", AdapterController.class.getDeclaredMethod("myTest4", HttpServletRequest.class));
         *
         */


        // 带多个参数的get方法
        /*
        RequestMappingInfo requestMappingInfo2 = RequestMappingInfo.paths("/lmcTest3")
                .params(new String[]{"fileName", "type", "isSort"})
                .methods(RequestMethod.GET).build();
        requestMappingHandlerMapping.registerMapping(requestMappingInfo2, "adapterController",
                AdapterController.class.getDeclaredMethod("myTest3", String.class, String.class, Boolean.class));
        */

        /*
        requestMappingHandlerMapping.registerMapping(
                RequestMappingInfo.paths("/x/y/z/parametrizedHandler").methods(RequestMethod.GET)
                        .produces(MediaType.APPLICATION_JSON_VALUE).build(),
                this,
                QueryController.class.getDeclaredMethod("parametrizedHandler", String.class, HttpServletRequest.class));

         */
    }


    /**
     * //class annotated with @Controller
     * MyController controller = new MyController
     *
     * //register new controller object
     * webappContext.getBeanFactory().registerSingleton("myController", controller);
     *
     * //find all RequestMappingHandlerMappings in webappContext and refresh them
     * webappContext.getBeansOfType(RequestMappingHandlerMapping.class)
     * .forEach((k, v) -> v.afterPropertiesSet());
     *
     *
     * requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping);
     *
     * So a complete code would look like this:
     *
     * applicationContext.getBeansOfType(RequestMappingHandlerMapping.class).forEach((name, requestMappingHandlerMapping) -> {
     * requestMappingHandlerMapping.getHandlerMethods().keySet().forEach(requestMappingHandlerMapping::unregisterMapping);
     * requestMappingHandlerMapping.afterPropertiesSet();
     * });
     * This must be executed after a new RestController has been registered as a bean.
     */

}